package org.glutenberg;

import java.io.IOException;
import java.util.Vector;

import org.glutenberg.dao.ProductReader;
import org.glutenberg.model.Brand;
import org.glutenberg.model.Category;
import org.glutenberg.model.Product;

import com.sun.lwuit.Command;
import com.sun.lwuit.Component;
import com.sun.lwuit.Container;
import com.sun.lwuit.Display;
import com.sun.lwuit.Font;
import com.sun.lwuit.Form;
import com.sun.lwuit.Label;
import com.sun.lwuit.TextArea;
import com.sun.lwuit.events.ActionEvent;
import com.sun.lwuit.events.ActionListener;
import com.sun.lwuit.layouts.BoxLayout;
import com.sun.lwuit.plaf.Style;

public class Results extends Form implements ActionListener {
	private Command exit;
	private Command find;
	private Command aboutCommand;
	private ProductReader reader;
	private Handbook hb;
	private int page = 0;
	private Component first;
	private Component last;

	public static String TITLE = "Risultati della ricerca";
	
	public Results(Handbook hb){
		this.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
		this.setCyclicFocus(false);
		this.hb = hb;
		this.setTitleComponent(this.getTitle(TITLE));
		this.exit = new Command("Esci");
		this.find = new Command("Cerca");
		this.aboutCommand =  About.getAboutCommand();
		this.addCommandListener(this);
		this.addCommand(this.find);
		this.addCommand(this.exit);
		this.addCommand(this.aboutCommand);
	}

	public void keyPressed(int keyCode) {
		int code = Display.getInstance().getGameAction(keyCode);
		if(code==Display.GAME_DOWN && this.reader.size() > 20 * (this.page+1) && this.last.hasFocus()){
			try {
				this.nextPage();
			} catch (IOException e){}
		} else if(code==Display.GAME_UP && this.page>0 && this.first.hasFocus()){
			try {
				this.previousPage();
			} catch (IOException e){}
		} else super.keyPressed(keyCode);
	}
	
	private void previousPage() throws IOException {
		this.page--;
		this.updateList();
		this.goToLast();
	}

	private void nextPage() throws IOException{
		this.page++;
		this.updateList();
		this.goToFirst();
	}
	
	private void goToFirst(){
		this.first.requestFocus();
		this.revalidate();
		this.refreshTheme();
		this.scrollComponentToVisible(this.first);		
	}

	private void goToLast(){
		this.last.requestFocus();
		this.revalidate();
		this.refreshTheme();
		this.scrollComponentToVisible(this.last);	
	}	
	
	private void createResultList(Vector products){
		this.removeAll();
		Category cat = null;
		Brand brand = null;
		int index = 0;
		for(int i=0;i<products.size();i++){
			Product p = (Product)products.elementAt(i);
			if(p.getCategory()!=cat){
				cat = p.getCategory();
				brand = null;
				Label catLabel = this.getCategoryLabel(cat);
				this.addComponent(index, catLabel);
				if(index==0) this.first = catLabel;
				index++;
			}
			if(p.getBrand() != brand){
				brand = p.getBrand();
				this.addComponent(index, this.getBrandLabel(brand));
				index++;
			}
			TextArea pLabel = this.getProductLabel(p);
			this.addComponent(index, this.getProductContainer(pLabel));			
			index++;
			if(i==products.size()-1) this.last = pLabel;
		}
		int pages = this.reader.size() / 20 + 1;
		this.getTitleComponent().setText(TITLE + " (" + (this.page +1) + "/" + pages + ")");
	}

	public static Label getTitle(String title){
		Label titleL = new Label(title);
		Style s = new Style();
		s.setFont(Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_MEDIUM));
		titleL.setSelectedStyle(s);
		titleL.setUnSelectedStyle(s);
		titleL.setAlignment(CENTER);
		return titleL;
	}	
	
	private Label getCategoryLabel(Category cat){
		Label titleL = new Label(cat.getName().toUpperCase() + " - " + cat.getEnglishName().toUpperCase());
		titleL.setFocusable(true);
		Style s = new Style();
		s.setFont(Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_LARGE));
		Style s1 = new Style(s);
		s1.setBgColor(0x000000);
		s1.setFgColor(0xffffff);
		titleL.setSelectedStyle(s1);
		titleL.setUnSelectedStyle(s);
		titleL.setAlignment(CENTER);
		return titleL;
	}
	
	private Label getBrandLabel(Brand brand){
		Label titleL = new Label(brand.getName().toUpperCase());
		titleL.setShiftText(Display.getInstance().getDisplayWidth()/10);
		titleL.setFocusable(true);
		Style s = new Style();
		s.setFont(Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_ITALIC, Font.SIZE_LARGE));
		Style s1 = new Style(s);
		s1.setBgColor(0x000000);
		s1.setFgColor(0xffffff);
		titleL.setSelectedStyle(s1);
		titleL.setUnSelectedStyle(s);
		return titleL;
	}
	
	private TextArea getProductLabel(Product p){
        TextArea titleL = new TextArea();
        titleL.setEditable(false);
        String attributes = "";
        if(p.isSpiga() || p.isMinistero() || p.isGrossista()){
        	attributes += "[";
        	if(p.isSpiga()) attributes += "S";
        	if(p.isMinistero()) attributes += "M";
        	if(p.isGrossista()) attributes += "G";
        	attributes += "]";
        }
        titleL.setText(attributes + " " + p.getName());
		titleL.setFocusable(true);
		Style s = new Style();
		s.setBorder(null);
		s.setFgColor(0x000);
		s.setFont(Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_MEDIUM));
		Style s1 = new Style(s);
		s1.setBgColor(0x000000);
		s1.setFgColor(0xffffff);
		titleL.setSelectedStyle(s1);
		titleL.setUnSelectedStyle(s);
		return titleL;
	}
	
	private Container getProductContainer(TextArea l){
		Container ret = new Container();
		BoxLayout layout = new BoxLayout(BoxLayout.X_AXIS);
		ret.setLayout(layout);
		Label first = new Label(" - ");
		first.setTextPosition(TOP);
		first.setTextPosition(RIGHT);
		first.setVerticalAlignment(TOP);
		ret.addComponent(first);
		ret.addComponent(l);
		return ret;
	}
	
	private void updateList() throws IOException{
		this.createResultList(this.reader.readProducts(this.page * 20, 20));
	}
	
	public void setProductReader(ProductReader reader) throws IOException{
		this.reader = reader;
		this.page = 0;
		this.updateList();
		this.goToFirst();
	}

	public void actionPerformed(ActionEvent ev) {
		Command c = ev.getCommand();
		if(c==this.exit){
			this.hb.quit();
		} else if(c==this.find){
			this.hb.find();
		} else if(c==this.aboutCommand){
			this.hb.about(this);
		}
	}
}
